package com.zx.cloud.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.LinkedHashMap;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

public class CookieUtil {

	private Logger logger = Logger.getLogger(CookieUtil.class);

	private HttpServletRequest request = null;
	private HttpServletResponse response = null;
	private CookieManager cookieManager = null;
	private LinkedHashMap<String, String> cookieMap = null;
	private static final String[] COOKIE_ID_ARR = { "TP", "TD", "TT" };
	private static final String CK_SEPERATOR = "#";
	private static final String VALUE_SEPERATOR = "|";
	private static final int TD_PERIOD = 86400;
	private static final int TT_PERIOD = 10 * 365 * TD_PERIOD;
	private static final String TMALL_DOMAIN = ".goreee.com";
	public static final int TP = 0;
	public static final int TD = 1;
	public static final int TT = 2;

	public CookieUtil(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
		cookieManager = new CookieManager(request, response);
		cookieMap = new LinkedHashMap<String, String>();
		setCookieDataBox();
	}

	private void setCookieDataBox() {
		try {
			Cookie[] cookies = request.getCookies();
			if (cookies != null) {
				String cookieName = "";
				for (int index = 0; index < cookies.length; index++) {
					cookieName = cookies[index].getName();
					for (int cookieIdIndex = 0; cookieIdIndex < COOKIE_ID_ARR.length; cookieIdIndex++) {
						if (StringUtils.equals(cookieName, COOKIE_ID_ARR[cookieIdIndex])) {
							cookieMap.put(COOKIE_ID_ARR[cookieIdIndex], URLDecoder.decode(cookies[index].getValue(), getDecodeCharSet()));
						}
					}
				}
			}
		} catch (UnsupportedEncodingException e) {
			if (logger.isDebugEnabled()) {
				logger.debug(e.getMessage());
			}
		}
	}

	private void make(int cookieIdIndex, String establishedCookieStr) {
		try {
			if (StringUtils.isNotBlank(establishedCookieStr)) {
				String encodedCookieStr = URLEncoder.encode(stripSharp(establishedCookieStr), getEncodeCharSet());
				Cookie cookie = new Cookie(COOKIE_ID_ARR[cookieIdIndex], encodedCookieStr);
				if (cookieIdIndex == 1) {
					cookie.setMaxAge(TD_PERIOD);
				} else if (cookieIdIndex == 2) {
					cookie.setMaxAge(TT_PERIOD);
				}
				cookie.setDomain(TMALL_DOMAIN);
				cookie.setPath("/");
				response.addCookie(cookie);
				cookieMap.put(COOKIE_ID_ARR[cookieIdIndex], establishedCookieStr);
			} else {
				Cookie cookie = new Cookie(COOKIE_ID_ARR[cookieIdIndex], "");
				cookie.setMaxAge(0);
				cookie.setDomain(TMALL_DOMAIN);
				cookie.setPath("/");
				response.addCookie(cookie);
				cookieManager.removeCookie(COOKIE_ID_ARR[cookieIdIndex]);
				cookieMap.remove(COOKIE_ID_ARR[cookieIdIndex]);
			}
		} catch (UnsupportedEncodingException e) {
			if (logger.isDebugEnabled()) {
				logger.debug(e.getMessage());
			}
		}
	}

	public void add(int cookieIdIndex, String cookieName) {
		add(cookieIdIndex, cookieName, "");
	}

	public void add(int cookieIdIndex, String cookieName, String cookieValue) {
		String cookieId = COOKIE_ID_ARR[cookieIdIndex];
		if (StringUtils.isNotBlank(cookieId) && StringUtils.isNotBlank(removeAllSeperator(cookieName).trim())) {
			cookieName = removeAllSeperator(cookieName).trim();
			String newCookieStr = cookieName;
			if (StringUtils.isNotBlank(removeAllSeperator(cookieValue).trim())) {
				newCookieStr += VALUE_SEPERATOR + removeAllSeperator(cookieValue).trim();
			}
			StringBuilder newCookieSb = new StringBuilder();
			if (isExistCookie(cookieIdIndex)) {
				String[] preexistCookieArr = StringUtils.split(stripSharp(cookieMap.get(COOKIE_ID_ARR[cookieIdIndex])), CK_SEPERATOR);
				for (int index = 0; index < preexistCookieArr.length; index++) {
					if (!StringUtils.equals(cookieName, StringUtils.split(preexistCookieArr[index], VALUE_SEPERATOR)[0])) {
						newCookieSb.append(CK_SEPERATOR).append(preexistCookieArr[index]);
					}
				}
			}
			newCookieSb.append(CK_SEPERATOR).append(newCookieStr);
			String establishedCookieStr = stripSharp(newCookieSb.toString());
			clear(cookieIdIndex);
			make(cookieIdIndex, establishedCookieStr);
		}
	}

	public boolean clear(int cookieIdIndex) {
		make(cookieIdIndex, "");
		return !isExistCookie(cookieIdIndex);
	}

	public boolean remove(int cookieIdIndex, String cookieName) {
		String cookieId = "";
		cookieId = COOKIE_ID_ARR[cookieIdIndex];
		boolean isRemoved = false;
		if (StringUtils.isNotBlank(cookieId)) {
			if (isExist(cookieIdIndex, cookieName)) {
				StringBuilder newCookieSb = new StringBuilder();
				String[] preexistCookieArr = StringUtils.split(stripSharp(cookieMap.get(cookieId)), CK_SEPERATOR);
				int preexistCookieCnt = preexistCookieArr.length;
				for (int index = 0; index < preexistCookieCnt; index++) {
					if (!StringUtils.equals(cookieName, StringUtils.split(preexistCookieArr[index], VALUE_SEPERATOR)[0])) {
						newCookieSb.append(CK_SEPERATOR).append(preexistCookieArr[index]);
					}
				}
				String establishedCookieStr = stripSharp(newCookieSb.toString());
				clear(cookieIdIndex);
				if (!isExist(cookieIdIndex, cookieName)) {
					isRemoved = true;
				}
				make(cookieIdIndex, establishedCookieStr);
			}
		}
		return isRemoved;
	}

	public boolean isExistCookie(int cookieIdIndex) {
		return cookieMap.containsKey(COOKIE_ID_ARR[cookieIdIndex]);
	}

	public boolean isExist(int cookieIdIndex, String cookieName) {
		String subCookieStr = cookieMap.get(COOKIE_ID_ARR[cookieIdIndex]);
		if (StringUtils.isBlank(subCookieStr)) {
			return false;
		}
		String[] subCookieArr = StringUtils.split(subCookieStr, CK_SEPERATOR);
		if (subCookieArr == null || subCookieArr.length < 1) {
			return false;
		}
		for (int index = 0; index < subCookieArr.length; index++) {
			String[] subCookie = StringUtils.split(subCookieArr[index], VALUE_SEPERATOR);
			if (subCookie != null && StringUtils.equals(subCookie[0], cookieName)) {
				return true;
			}
		}
		return false;
	}

	public String getCookie(int cookieIdIndex) {
		String cookieString = "";
		if (isExistCookie(cookieIdIndex)) {
			cookieString = cookieMap.get(COOKIE_ID_ARR[cookieIdIndex]);
		}
		return cookieString;
	}

	public String getCookie(String cookieId) {
		if (cookieMap.containsKey(cookieId)) {
			return cookieMap.get(cookieId);
		}
		return null;
	}

	public String getSubCookie(int cookieIdIndex, String cookieName) {
		String cookieString = "";
		String cookieValue = "";
		if (isExist(cookieIdIndex, cookieName)) {
			cookieString = getCookie(cookieIdIndex);
		}
		if (StringUtils.isNotBlank(cookieString)) {
			String[] cookieArr = StringUtils.split(cookieString, CK_SEPERATOR);
			for (int index = 0; index < cookieArr.length; index++) {
				String[] cookie = StringUtils.split(cookieArr[index], VALUE_SEPERATOR);
				if (StringUtils.equals(cookieName, cookie[0])) {
					return cookie[1];
				}
			}
		}
		return cookieValue;
	}

	public String stripSharp(String param) {
		String returnParam = "";
		if (StringUtils.isBlank(param)) {
			return returnParam;
		} else {
			return StringUtils.strip(param, CK_SEPERATOR).trim();
		}
	}

	public String removeCookieSeperator(String param) {
		String returnParam = "";
		if (StringUtils.isBlank(param)) {
			return returnParam;
		} else {
			return param.replaceAll("\\" + CK_SEPERATOR, "");
		}
	}

	public String removeValueSeperator(String param) {
		String returnParam = "";
		if (StringUtils.isBlank(param)) {
			return returnParam;
		} else {
			return param.replaceAll("\\" + VALUE_SEPERATOR, "");
		}
	}

	public String removeAllSeperator(String param) {
		return removeValueSeperator(removeCookieSeperator(param));
	}

	public String getComment() {
		return cookieManager.getComment();
	}

	public void setComment(String comment) {
		cookieManager.setComment(comment);
	}

	public String getDomain() {
		return cookieManager.getDomain();
	}

	public void setDomain(String domain) {
		cookieManager.setDomain(domain);
	}

	public int getMaxAge() {
		return cookieManager.getMaxAge();
	}

	public void setMaxAge(int maxAge) {
		cookieManager.setMaxAge(maxAge);
	}

	public String getPath() {
		return cookieManager.getPath();
	}

	public void setPath(String path) {
		cookieManager.setPath(path);
	}

	public HttpServletRequest getRequest() {
		return this.request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return this.response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public boolean isSecure() {
		return cookieManager.isSecure();
	}

	public void setSecure(boolean secure) {
		cookieManager.setSecure(secure);
	}

	public String getEncodeCharSet() {
		return cookieManager.getEncodeCharSet();
	}

	public void setEncodeCharSet(String encodeCharSet) {
		cookieManager.setEncodeCharSet(encodeCharSet);
	}

	public String getDecodeCharSet() {
		return cookieManager.getDecodeCharSet();
	}

	public void setDecodeCharSet(String decodeCharSet) {
		cookieManager.setDecodeCharSet(decodeCharSet);
	}

}
